LiquidMigrator is checking for complex JSONPaths

If a complex JSONPath like '$.text[*]' is found the migration will
fail with an exception and keep the database intact

Dominik Sander 11 years ago
parent
commit
b4b9939b7d
3 changed files with 31 additions and 8 deletions
  1. 2 2
      app/concerns/liquid_interpolatable.rb
  2. 10 3
      lib/liquid_migrator.rb
  3. 19 3
      spec/lib/liquid_migrator_spec.rb

+ 2 - 2
app/concerns/liquid_interpolatable.rb

@@ -1,7 +1,7 @@
1 1
 module LiquidInterpolatable
2 2
   extend ActiveSupport::Concern
3 3
 
4
-  def interpolate_options options, payload
4
+  def interpolate_options(options, payload)
5 5
     duped_options = options.dup.tap do |duped_options|
6 6
       duped_options.each_pair do |key, value|
7 7
         if value.class == String
@@ -14,7 +14,7 @@ module LiquidInterpolatable
14 14
     duped_options
15 15
   end
16 16
 
17
-  def interpolate_string string, payload
17
+  def interpolate_string(string, payload)
18 18
     Liquid::Template.parse(string).render(payload)
19 19
   end
20 20
 

+ 10 - 3
lib/liquid_migrator.rb

@@ -20,9 +20,9 @@ module LiquidMigrator
20 20
           end
21 21
           hash[key] = LiquidMigrator.convert_string value, options[:leading_dollarsign_is_jsonpath]
22 22
         when 'Hash'
23
-          # might want to make it recursive?
23
+          raise "nested Hashes are not supported at the moment"
24 24
         when 'Array'
25
-          # do we need it?
25
+          raise "nested Arrays are not supported at the moment"
26 26
         end
27 27
       end
28 28
         # remove the unneeded *_path attributes
@@ -51,7 +51,14 @@ module LiquidMigrator
51 51
   end
52 52
 
53 53
   def self.convert_json_path(string, filter = "")
54
-    "{{#{string[2..-1].gsub(/\.\*\Z/, '')}#{filter}}}"
54
+    check_path(string)
55
+    "{{#{string[2..-1]}#{filter}}}"
56
+  end
57
+
58
+  def self.check_path(string)
59
+    if string !~ /\A(\$\.)?(\w+\.)*(\w+)\Z/
60
+      raise "JSONPath '#{string}' is too complex, please check your migration."
61
+    end
55 62
   end
56 63
 end
57 64
 

+ 19 - 3
spec/lib/liquid_migrator_spec.rb

@@ -5,7 +5,6 @@ describe LiquidMigrator do
5 5
     it "should work" do
6 6
       LiquidMigrator.convert_string("$.data", true).should == "{{data}}"
7 7
       LiquidMigrator.convert_string("$.data.test", true).should == "{{data.test}}"
8
-      LiquidMigrator.convert_string("$.data.test.*", true).should == "{{data.test}}"
9 8
     end
10 9
 
11 10
     it "should ignore strings which just contain a JSONPath" do
@@ -13,12 +12,14 @@ describe LiquidMigrator do
13 12
       LiquidMigrator.convert_string(" $.data", true).should == " $.data"
14 13
       LiquidMigrator.convert_string("lorem $.data", true).should == "lorem $.data"
15 14
     end
15
+    it "should raise an exception when encountering complex JSONPaths" do
16
+      expect { LiquidMigrator.convert_string("$.data.test.*", true) }.
17
+        to raise_error("JSONPath '$.data.test.*' is too complex, please check your migration.")
18
+    end
16 19
   end
17 20
 
18 21
   describe "converting escaped JSONPath strings" do
19 22
     it "should work" do
20
-      LiquidMigrator.convert_string("Received <$.content.text.*> from <$.content.name> .").should ==
21
-                                    "Received {{content.text}} from {{content.name}} ."
22 23
       LiquidMigrator.convert_string("Weather looks like <$.conditions> according to the forecast at <$.pretty_date.time>").should ==
23 24
                                     "Weather looks like {{conditions}} according to the forecast at {{pretty_date.time}}"
24 25
     end
@@ -27,6 +28,11 @@ describe LiquidMigrator do
27 28
       LiquidMigrator.convert_string("Escaped: <escape $.content.name>\nNot escaped: <$.content.name>").should ==
28 29
                                     "Escaped: {{content.name | uri_escape}}\nNot escaped: {{content.name}}"
29 30
     end
31
+
32
+    it "should raise an exception when encountering complex JSONPaths" do
33
+      expect { LiquidMigrator.convert_string("Received <$.content.text.*> from <$.content.name> .") }.
34
+        to raise_error("JSONPath '$.content.text.*' is too complex, please check your migration.")
35
+    end
30 36
   end
31 37
 
32 38
   describe "migrating a hash" do
@@ -42,6 +48,10 @@ describe LiquidMigrator do
42 48
       LiquidMigrator.convert_hash({'a' => "default", 'a_path' => "$.data"}, {leading_dollarsign_is_jsonpath: true, merge_path_attributes: true}).should ==
43 49
                                   {'a' => "{{data}}"}
44 50
     end
51
+    it "should raise an exception when encountering complex JSONPaths" do
52
+      expect { LiquidMigrator.convert_hash({'b' => "This is <$.complex[2]>"}) }.
53
+        to raise_error("JSONPath '$.complex[2]' is too complex, please check your migration.")
54
+    end
45 55
   end
46 56
 
47 57
   describe "migrating an actual agent" do
@@ -69,5 +79,11 @@ describe LiquidMigrator do
69 79
       LiquidMigrator.convert_all_agent_options(@agent)
70 80
       @agent.reload.options.should == {"auth_token" => 'token', 'color' => 'yellow', 'notify' => false, 'room_name' => 'test', 'username' => '{{username}}', 'message' => '{{message}}'}
71 81
     end
82
+
83
+    it "should raise an exception when encountering complex JSONPaths" do
84
+      @agent.options['username_path'] = "$.very.complex[*]"
85
+      expect { LiquidMigrator.convert_all_agent_options(@agent) }.
86
+        to raise_error("JSONPath '$.very.complex[*]' is too complex, please check your migration.")
87
+    end
72 88
   end
73 89
 end